package com.ddstation.instrument_disinfect.service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import javax.inject.Inject;

import com.ddstation.app.holiday.service.HolidayService;
import com.ddstation.common.util.GeneralCheckUtil;
import com.ddstation.crud.entity.DtInvsIllegalCheckDailyEntity;
import com.ddstation.crud.mapper.DtInvsIllegalCheckDailyMapper;
import com.ddstation.home_page.service.DtInvsMessageQueueService;
import com.ddstation.instrument_disinfect.constant.UltravioletEnum;
import com.ddstation.instrument_disinfect.constant.UltravioletOperationTypeEnum;
import com.ddstation.instrument_disinfect.mapper.DtInvsInstitutionUltravioletInstrumentMapper;
import com.ddstation.instrument_disinfect.mapper.DtInvsInstrumentDisinfectUltravioletMapper;
import com.ddstation.instrument_disinfect.mapper.DtInvsUltravioletChangeRecordMapper;
import com.ddstation.instrument_disinfect.model.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ddstation.common.model.InvsCheckCommonSchParModel;
import com.ddstation.common.model.SimpleModel;
import com.ddstation.crud.entity.DtInvsInstrumentDisinfectDetailEntity;
import com.ddstation.crud.entity.DtInvsInstrumentDisinfectEntity;
import com.ddstation.crud.entity.DtInvsInstrumentEntity;
import com.ddstation.crud.mapper.DtInvsInstrumentDisinfectDetailMapper;
import com.ddstation.crud.mapper.DtInvsInstrumentDisinfectMapper;
import com.ddstation.crud.mapper.DtInvsInstrumentMapper;
import com.ddstation.instrument_disinfect.mapper.InstrumentDisinfectMapper;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;


@Service @Lazy
public class InstrumentDisinfectServiceImpl implements InstrumentDisinfectService {
	// 查询
	@Override
	@Transactional(readOnly=true)
	public List<InstrumentDisinfectResModel> searchInstrumentDisinfectList(InvsCheckCommonSchParModel _in){
		return instrumentDisinfectMapper.selectInstrumentDisinfectList(_in);
	}
	
	// 查询明细
	@Override
	@Transactional(readOnly=true)
	public List<InstrumentDisinfectHeadResModel> searchDetailList(InstrumentDisinfectDetailParModel _in){

		List<InstrumentDisinfectHeadResModel> list = null;

		if ( _in.getBusinessSubType() == 101 ){ // 器械消毒
			list =  instrumentDisinfectMapper.selectDetail(_in);
		} else 	if ( _in.getBusinessSubType() == 102 ){ // 场所消毒
			// 把daily表中对应的记录查询出来 场所消毒登记记录的id存在check_daily表的comment字段中

			// 查询daily
			List<InstrumentDisinfectHeadResModel> listDaily = instrumentDisinfectMapper.selectDetail(_in);
			// 查询对应的场所消毒记录
			String ids = instrumentDisinfectMapper.selectAreaIds(_in);
			// 无场所消毒记录，直接返回daily数据
			if ( StringUtils.isBlank(ids)){
				return listDaily;
			}

			// check记录对应的场所消毒记录
			List<InstrumentDisinfectHeadResModel> listArea = instrumentDisinfectMapper.selectAreaListByIds(ids.split(","));
			if ( listArea == null || listArea.size()==0 ){
				// 未查询到明细时，直接返回
				return listDaily;
			}

			list = new ArrayList<InstrumentDisinfectHeadResModel>();// merge list

			for ( InstrumentDisinfectHeadResModel _one:listDaily ){
				// 找到同一天的数据
				List<InstrumentDisinfectHeadResModel> fillerList = listArea.stream().filter(a->a.getSerialDate().equals(_one.getSerialDate())).
						collect(Collectors.toList());
				if (fillerList == null || fillerList.size()==0){
					list.add(_one);
				} else {
					// 同一天有多个场所进行了消毒
					for ( InstrumentDisinfectHeadResModel _b:fillerList ){
						InstrumentDisinfectHeadResModel _newOne = new InstrumentDisinfectHeadResModel();
						BeanUtils.copyProperties(_one,_newOne);
						_newOne.setInstrumentName(_b.getInstrumentName());
						_newOne.setDisinfectTypeTxt(_b.getDisinfectTypeTxt());

						_newOne.getHeadEntity().setDisinfectStartTm(_b.getHeadEntity().getDisinfectStartTm());
						_newOne.getHeadEntity().setDisinfectEndTm(_b.getHeadEntity().getDisinfectEndTm());
						_newOne.getHeadEntity().setPaperImgId(_b.getHeadEntity().getPaperImgId());

						list.add(_newOne);
					}
				}
			}
		}

		return list;
	}

	// 查询机构下所有器械
	public List<DtInvsInstrumentEntity> searchInstrumentList(String institutionId,int type){
		return dtInvsInstrumentMapper.selectByInstitutionId(institutionId,type);
	}

	@Override
	public List<InstrumentDisinfectHeadResModel> selectByHistory(String institutionId, Integer instrumentType, int pageNo, int pageSize) {
		int startNo = (pageNo - 1) * pageSize;
		return instrumentDisinfectMapper.selectByHistory(institutionId,instrumentType,startNo,pageSize);
	}

	@Override
	public List<SimpleModel> selectByInstrumentName(String institutionId, Integer instrumentType) {
		return instrumentDisinfectMapper.selectByInstrumentName(institutionId,instrumentType);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public int addInstrumentName(String institutionId, Integer instrumentType,String name) {
		return instrumentDisinfectMapper.insertInstrumentName(institutionId,instrumentType,name);
	}

	@Override
	public List<String> checkByInstrumentName(String institutionId, Integer instrumentType,String name) {
		return instrumentDisinfectMapper.checkByInstrumentName(institutionId,instrumentType,name);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public int delInstrumentName(String institutionId, Integer instrumentType,Integer id) {
		return instrumentDisinfectMapper.deleteInstrumentName(institutionId,instrumentType,id);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public Map<String, Object> addInstrumentDisinfect(DtInvsInstrumentDisinfectEntity entity, String itemList, DtInvsInstrumentDisinfectUltravioletModel ultravioletModel) {
		Map<String, Object> retMap = new HashMap<String, Object>();
		int cnt = dtInvsInstrumentDisinfectMapper.insert(entity);
		if (cnt <= 0) {
			throw new RuntimeException("机械或场所消毒创建记表失败");
		}
		List<DtInvsInstrumentDisinfectDetailEntity> detailEntityList = new ArrayList<DtInvsInstrumentDisinfectDetailEntity>();
		JSONArray jsonBean = null;
		try {
			jsonBean = JSONArray.fromObject(itemList);
			for(int i=0; i<jsonBean.size(); i++) {
				DtInvsInstrumentDisinfectDetailEntity detailEntity = new DtInvsInstrumentDisinfectDetailEntity();
				detailEntity.setDisinfectId(entity.getId());
				JSONObject sObj = (JSONObject)jsonBean.get(i);
				detailEntity.setInstrumentId(sObj.getInt("id"));
				if (entity.getInstrumentType().intValue() == 1) {
					detailEntity.setQuantity(sObj.get("quantity").toString());

				} else {
					detailEntity.setQuantity("1");
				}
				detailEntityList.add(detailEntity);
			}
		} catch (Exception e) {
			retMap.put("errCode", -1);
			retMap.put("errormsg", "请填写数量（数值类型）");
			throw new RuntimeException("请填写数量（数值类型）");
		}
		if (detailEntityList.size() <= 0) {
			throw new RuntimeException("机械或场所List为空");
		}
		dtInvsInstrumentDisinfectDetailMapper.insertList(detailEntityList);

		// 保存场所消毒紫外线使用记录
		if (null != ultravioletModel) {
			ultravioletModel.setDisinfectId(entity.getId());
			DtInvsInstitutionUltravioletInstrumentModel ultraLamp = dtInvsInstitutionUltravioletInstrumentMapper.selectOne(ultravioletModel.getUltravioletId());
			// 更新紫外线灯的已用时间
			if (null != ultraLamp) {
				ultraLamp.setUseTime(null == ultraLamp.getUseTime() ? ultravioletModel.getDisinfectDuration() : ultraLamp.getUseTime() + ultravioletModel.getDisinfectDuration());
				if (ultraLamp.getMaxTime() <= ultraLamp.getUseTime()) {
					ultraLamp.setStatus(UltravioletEnum.OUTOFDATE.getValue());
				}
				dtInvsInstitutionUltravioletInstrumentMapper.updateSelective(ultraLamp);
			}
			dtInvsInstrumentDisinfectUltravioletMapper.insert(ultravioletModel);
		}
		//新增消息
		if (entity.getInstrumentType() == 1) {
			dtInvsMessageQueueService.insertMessageQueue(entity.getInstitutionId(),101,2,1,entity.getId().toString(),1);
		} else {
			dtInvsMessageQueueService.insertMessageQueue(entity.getInstitutionId(),102,2,1,entity.getId().toString(),1);
		}

		// 卫监记录
		Date today = new Date();
		List<DtInvsIllegalCheckDailyEntity> checkList = dtInvsIllegalCheckDailyMapper.selectOneByDateAndInstitution(today, entity.getInstitutionId());
		if (null != checkList && !checkList.isEmpty()) {
			for (DtInvsIllegalCheckDailyEntity ele: checkList) {
				if (ele.getBusinessSubType() == 101 && entity.getInstrumentType() == 1) {
					ele.setTargetId(entity.getId().toString());//取最近一次登记的记录
					ele.setCheckSt(0);
					dtInvsIllegalCheckDailyMapper.updateByPrimaryKeySelective(ele);

					retMap.put("errCode", 0);
					retMap.put("errormsg", "");
					return retMap;
				}
				if (ele.getBusinessSubType() == 102 && entity.getInstrumentType() == 2) {
					ele.setTargetId(entity.getId().toString());//取最近一次登记的记录
					ele.setCheckSt(0);
					dtInvsIllegalCheckDailyMapper.updateByPrimaryKeySelective(ele);

					retMap.put("errCode", 0);
					retMap.put("errormsg", "");
					return retMap;
				}
			}
		}
		DtInvsIllegalCheckDailyEntity _checkRet1 = new DtInvsIllegalCheckDailyEntity();// 一条check结果
		_checkRet1.setInstitutionId( entity.getInstitutionId());//机构ID
		_checkRet1.setCheckDt(today);//检查日期
		_checkRet1.setBusinessType(10);//'@10：消毒登记 @20：医废登记 @30：检测审查 @40：处方违规',
		if (entity.getInstrumentType() == 1) {
			_checkRet1.setBusinessSubType(101);//'子分类 @101：器械消毒
		} else {
			_checkRet1.setBusinessSubType(102);//'子分类 @102：场所消毒
		}
		String dateStr = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.ofInstant(today.toInstant(), ZoneId.systemDefault()));
		if (holidayService.checkHoliday(dateStr, entity.getInstitutionId())) {
			_checkRet1.setMsgId("900008");
			_checkRet1.setMessage("休息日");
		}
		_checkRet1.setCheckSt(0);//正常
		_checkRet1.setTargetId(entity.getId().toString());//取最近一次登记的记录
		dtInvsIllegalCheckDailyMapper.insert(_checkRet1);

		retMap.put("errCode", 0);
		retMap.put("errormsg", "");
		return retMap;
	}

	@Override
	public DtInvsInstrumentDisinfectEntity instrumentDisinfectDetail(String institutionId, Integer id) {
		return dtInvsInstrumentDisinfectDetailMapper.selectForDetail(id,institutionId);
	}

	@Override
	public List<DtInvsInstitutionUltravioletInstrumentModel> getUltravioletInstrumentsByInstitution(String institutionId, Integer status) {
		return dtInvsInstitutionUltravioletInstrumentMapper.selectByInstitutionIdAndStatus(institutionId, status);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveUltravioletInstrument(DtInvsInstitutionUltravioletInstrumentModel dtInvsInstitutionUltravioletInstrumentModel) {
		dtInvsInstitutionUltravioletInstrumentModel.setEnableDate(new Date());
		dtInvsInstitutionUltravioletInstrumentMapper.insert(dtInvsInstitutionUltravioletInstrumentModel);
		DtInvsUltravioletChangeRecordModel updateRecord = new DtInvsUltravioletChangeRecordModel();
		updateRecord.setInstitutionId(dtInvsInstitutionUltravioletInstrumentModel.getInstitutionId());
		updateRecord.setUltravioletId(dtInvsInstitutionUltravioletInstrumentModel.getId());
		updateRecord.setOperationType(UltravioletOperationTypeEnum.INSERT.getValue());
		updateRecord.setMaxTime(dtInvsInstitutionUltravioletInstrumentModel.getMaxTime());
		updateRecord.setUseTime(dtInvsInstitutionUltravioletInstrumentModel.getUseTime());
		updateRecord.setUltraStatus(dtInvsInstitutionUltravioletInstrumentModel.getStatus());
		return  dtInvsUltravioletChangeRecordMapper.insert(updateRecord) > 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateUltravioletInstrument(DtInvsInstitutionUltravioletInstrumentModel dtInvsInstitutionUltravioletInstrumentModel) {
		if (UltravioletEnum.NORMAL.getValue().equals(dtInvsInstitutionUltravioletInstrumentModel.getStatus())) {
			dtInvsInstitutionUltravioletInstrumentModel.setEnableDate(new Date());
			DtInvsInstitutionUltravioletInstrumentModel oldModel = dtInvsInstitutionUltravioletInstrumentMapper.selectOne(dtInvsInstitutionUltravioletInstrumentModel.getId());
			DtInvsUltravioletChangeRecordModel updateRecord = new DtInvsUltravioletChangeRecordModel();
			updateRecord.setInstitutionId(dtInvsInstitutionUltravioletInstrumentModel.getInstitutionId());
			updateRecord.setUltravioletId(dtInvsInstitutionUltravioletInstrumentModel.getId());
			updateRecord.setOperationType(UltravioletOperationTypeEnum.UPDATE.getValue());
			updateRecord.setMaxTime(oldModel.getMaxTime());
			updateRecord.setUseTime(oldModel.getUseTime());
			updateRecord.setUltraStatus(oldModel.getStatus());
			dtInvsUltravioletChangeRecordMapper.insert(updateRecord);
		}
		return dtInvsInstitutionUltravioletInstrumentMapper.updateSelective(dtInvsInstitutionUltravioletInstrumentModel) > 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean abandonUltravioletInstrument(Integer ultraId) {
		DtInvsInstitutionUltravioletInstrumentModel oldModel = dtInvsInstitutionUltravioletInstrumentMapper.selectOne(ultraId);
		if (null == oldModel) {
			return true;
		}
		DtInvsUltravioletChangeRecordModel updateRecord = new DtInvsUltravioletChangeRecordModel();
		updateRecord.setInstitutionId(oldModel.getInstitutionId());
		updateRecord.setUltravioletId(oldModel.getId());
		updateRecord.setOperationType(UltravioletOperationTypeEnum.DELETE.getValue());
		updateRecord.setMaxTime(oldModel.getMaxTime());
		updateRecord.setUseTime(oldModel.getUseTime());
		updateRecord.setUltraStatus(oldModel.getStatus());
		dtInvsUltravioletChangeRecordMapper.insert(updateRecord);
		DtInvsInstitutionUltravioletInstrumentModel updateModel = new DtInvsInstitutionUltravioletInstrumentModel();
		updateModel.setId(oldModel.getId());
		updateModel.setStatus(-1);
		dtInvsInstitutionUltravioletInstrumentMapper.updateSelective(updateModel);
		return true;
	}

	@Override
	public DtInvsInstrumentDisinfectUltravioletModel getUltravioletUsageByDisinfectId(Integer disinfectId) {
		return dtInvsInstrumentDisinfectUltravioletMapper.selectByDisinfectId(disinfectId);
	}

	@Override
	public List<UltravioletRecordDisplayModel> getUltravioletRecordsByInstitution(String institutionId) {
		List<UltravioletRecordDisplayModel> records = dtInvsUltravioletChangeRecordMapper.selectRecordWrapperByInstitutionId(institutionId);
		if (!GeneralCheckUtil.isEmptyList(records)) {
			for (UltravioletRecordDisplayModel record : records) {
				UltravioletOperationTypeEnum opEnum = UltravioletOperationTypeEnum.val(record.getOperationType());
				record.setOperationDesc(null == opEnum? "" : opEnum.getDesc());
			}
		}
		return records;
	}

	@Override
	public List<DtInvsUltravioletResModel> getInstitutionUltravioletByInvsInstitution(String institutionId, String name, Integer status,String institutionTypeFirst) {
		return dtInvsInstitutionUltravioletInstrumentMapper.getUltravioletInstitutionInfo(institutionId, name, status, institutionTypeFirst);
	}

	@Inject private DtInvsMessageQueueService dtInvsMessageQueueService;
	@Inject private DtInvsInstrumentDisinfectMapper dtInvsInstrumentDisinfectMapper;
	@Inject private DtInvsInstrumentDisinfectDetailMapper dtInvsInstrumentDisinfectDetailMapper;
	@Inject private InstrumentDisinfectMapper instrumentDisinfectMapper;
	@Inject private DtInvsInstrumentMapper dtInvsInstrumentMapper;
	@Inject private DtInvsInstitutionUltravioletInstrumentMapper dtInvsInstitutionUltravioletInstrumentMapper;
	@Inject private DtInvsInstrumentDisinfectUltravioletMapper dtInvsInstrumentDisinfectUltravioletMapper;
	@Inject private DtInvsUltravioletChangeRecordMapper dtInvsUltravioletChangeRecordMapper;
	@Inject private DtInvsIllegalCheckDailyMapper dtInvsIllegalCheckDailyMapper;
	@Inject private HolidayService holidayService;
}
